package cn.wolfcode.mycat.test;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.*;
import org.elasticsearch.action.support.replication.ReplicationResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * @author Create by dell on 2021/3/15.
 */
public class ElasticUtil {

    public static final String INDEX_NAME = "order-index";

    private static final Logger logger = LoggerFactory.getLogger(ElasticUtil.class);

    public static String createIndexSync(WmsCallRecordEntity callRecordEntity) throws IOException {
        RestHighLevelClient client;
        String index = "loading index......";
        try {
            client = RestClientConfiguration.getClient();
             index = UUID.randomUUID().toString();
            callRecordEntity.setCode(index);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            callRecordEntity.setCreateTime(format.format(new Date()));
            CreateIndexRequest request = new CreateIndexRequest(index);
            logger.info("打印索引{}", index);
            request.settings(Settings.builder().put("index.number_of_shards", 3)
                    .put("index.number_of_replicas", 2)
            );
            request.mapping("_doc",

                    "  {\n" +

                            "    \"_doc\": {\n" +

                            "      \"properties\": {\n" +

                            "        \"warehouseCode\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"code\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"recordCode\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"orderType\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"systemCode\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"requestService\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"requestUrl\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"requestContent\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"responseContent\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"createTime\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"status\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }," +

                            "        \"getWayCode\": {\n" +

                            "          \"type\": \"text\"\n" +

                            "        }\n" +

                            "      }\n" +

                            "    }\n" +

                            "  }",
                    XContentType.JSON);
            request.alias(new Alias(INDEX_NAME));
            RequestOptions requestOptions = RequestOptions.DEFAULT;
            //同步发送请求
            CreateIndexResponse createIndexResponse = client.indices().create(request, requestOptions);
            boolean acknowledged = createIndexResponse.isAcknowledged();
            logger.info("确认响应{}", acknowledged);
            boolean shardsAcknowledged = createIndexResponse.isShardsAcknowledged();
            logger.info("分片响应{}", shardsAcknowledged);
            //创建索引数据
            IndexRequest indexRequest = new IndexRequest(
                    /**
                     * 索引
                     */
                    index,
                    /**
                     * mapping type
                     */
                    "_doc",
                    /**
                     * 文档Id
                     */
                    "1");
            indexRequest.source(JSON.toJSONString(callRecordEntity), XContentType.JSON);

            //4、发送请求
            IndexResponse indexResponse = null;
            try {
                // 同步方式
                indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
            } catch (ElasticsearchException e) {
                if (e.status() == RestStatus.CONFLICT) {
                    logger.error("冲突，写入冲突逻辑\n" + e.getDetailedMessage());
                }
                logger.error("索引异常", e);
            }

            //5、处理响应
            if (indexResponse != null) {
                if (indexResponse.getResult() == DocWriteResponse.Result.CREATED) {
                    System.out.println("新增文档成功，处理逻辑.....");
                } else if (indexResponse.getResult() == DocWriteResponse.Result.UPDATED) {
                    System.out.println("修改文档成功，处理逻辑.....");
                }
                // 分片处理信息
                ReplicationResponse.ShardInfo shardInfo = indexResponse.getShardInfo();
                if (shardInfo.getTotal() != shardInfo.getSuccessful()) {

                }
                // 分片失败 获取分片失败原因
                if (shardInfo.getFailed() > 0) {
                    for (ReplicationResponse.ShardInfo.Failure failure : shardInfo.getFailures()) {
                        String reason = failure.reason();
                        System.out.println("副本失败原因：" + reason);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return index;
    }

    /**
     *查询es 数据
     * @param esEntity
     * @return
     */
    public String queryEsResponse(EsEntity esEntity) {

        String response = "开始搜索es数据......";

        try (RestHighLevelClient client = RestClientConfiguration.getClient()) {
            //创建获取文档请求
            GetRequest request = new GetRequest(
                    /**
                     * 索引
                     */
                    esEntity.getIndex(),
                    "_doc",
                    "1");
            /**
             * 选择返回的字段
             */
            String[] includes = new String[]{esEntity.getChooseChar()};
            String[] excludes = Strings.EMPTY_ARRAY;
            FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
            request.fetchSourceContext(fetchSourceContext);
            //3、发送请求
            GetResponse getResponse = null;
            try {
                // 同步请求
                getResponse = client.get(request, RequestOptions.DEFAULT);
            } catch (ElasticsearchException e) {
                if (e.status() == RestStatus.NOT_FOUND) {
                    logger.error("没有找到index的文档");
                }
                if (e.status() == RestStatus.CONFLICT) {
                    logger.error("获取时版本冲突，解决冲突逻辑");
                }
                logger.error("获取文档异常", e);
            }

            //4、处理响应
            if (getResponse != null) {
                String index = getResponse.getIndex();
                String type = getResponse.getType();
                String id = getResponse.getId();
                /**
                 * 文档存在
                 */
                if (getResponse.isExists()) {

                    long version = getResponse.getVersion();
                    /**
                     * 结果 String
                     */
                    response = getResponse.getSourceAsString();
                    /**
                     * 结果 Map
                     */
                    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
                    /**
                     * 结果 字节数组
                     */
                    byte[] sourceAsBytes = getResponse.getSourceAsBytes();

                    logger.info("index:" + index + "  type:" + type + "  id:" + id);
                    logger.info(JSONUtil.formatJsonStr(response));

                } else {
                    logger.error("没有找到index的文档");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return response;
    }

//    public static void main(String[] args) {
//        try (RestHighLevelClient client = RestClientConfiguration.getClient()) {
//            //创建获取文档请求
//            GetRequest request = new GetRequest(
//                    /**
//                     * 索引
//                     */
//                    "8d3a20c9-f913-4a98-9c78-ba5edf0f5a11",
//                    "_doc",
//                    "1");
//            /**
//             * 选择返回的字段
//             */
//            String[] includes = new String[]{"code","warehouseCode","recordCode","requestContent","createTime"};
//            String[] excludes = Strings.EMPTY_ARRAY;
//            FetchSourceContext fetchSourceContext = new FetchSourceContext(true, includes, excludes);
//            request.fetchSourceContext(fetchSourceContext);
//            //3、发送请求
//            GetResponse getResponse = null;
//            try {
//                // 同步请求
//                getResponse = client.get(request);
//            } catch (ElasticsearchException e) {
//                if (e.status() == RestStatus.NOT_FOUND) {
//                    logger.error("没有找到该id的文档");
//                }
//                if (e.status() == RestStatus.CONFLICT) {
//                    logger.error("获取时版本冲突了，请在此写冲突处理逻辑！");
//                }
//                logger.error("获取文档异常", e);
//            }
//
//            //4、处理响应
//            if (getResponse != null) {
//                String index = getResponse.getIndex();
//                String type = getResponse.getType();
//                String id = getResponse.getId();
//                /**
//                 * 文档存在
//                 */
//                if (getResponse.isExists()) {
//
//                    long version = getResponse.getVersion();
//                    /**
//                     * 结果 String
//                     */
//                    String str = getResponse.getSourceAsString();
//                    /**
//                     * 结果 Map
//                     */
//                    Map<String, Object> sourceAsMap = getResponse.getSourceAsMap();
//                    /**
//                     * 结果 字节数组
//                     */
//                    byte[] sourceAsBytes = getResponse.getSourceAsBytes();
//
//                    logger.info("index:" + index + "  type:" + type + "  id:" + id);
//                    logger.info(JSONUtil.formatJsonStr(str));
//
//                } else {
//                    logger.error("没有找到该id的文档");
//                }
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

    public static void main(String[] args) {
        MultiSearchRequest request = new MultiSearchRequest();
        SearchRequest firstSearchRequest = new SearchRequest();
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //范围查询
//        searchSourceBuilder.query(QueryBuilders.rangeQuery("createTime").gte("2021-03-19 21:29:00").lt("2021-03-19 21:29:00"));
        //精确匹配查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("orderType","THRK"));
        firstSearchRequest.source(searchSourceBuilder);
        request.add(firstSearchRequest);
        try {
            MultiSearchResponse response = RestClientConfiguration.getClient().msearch(request, RequestOptions.DEFAULT);
            response.forEach(t -> {
                SearchResponse resp = t.getResponse();

                Arrays.stream(resp.getHits().getHits())
                        .forEach(i -> {
                            System.out.println(i.getId());
                            System.out.println(i.getIndex());
                            System.out.println(i.getSourceAsString());
                            System.out.println(i.getSourceAsMap().get("createTime"));
                        });
                System.out.println(resp.getHits().getTotalHits());
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
